package com.ctsi.system.app.rest;

import com.ctsi.commons.util.UtilValidate;
import com.ctsi.commons.util.request.UtilHttp;
import com.ctsi.commons.util.response.Page;
import com.ctsi.framework.common.response.UnifiedResponse;
import com.ctsi.framework.organise.security.UserInfo;
import com.ctsi.framework.security.util.SecurityUtil;
import com.ctsi.system.app.rest.request.AddTreeDataRequest;
import com.ctsi.system.app.rest.request.AddTreeTypeRequest;
import com.ctsi.system.app.rest.response.DictTreeDataResponse;
import com.ctsi.system.domain.DictionaryTreeData;
import com.ctsi.system.domain.DictionaryTreeType;
import com.ctsi.system.dto.DictTreeDataDTO;
import com.ctsi.system.service.DictionaryTreeDataService;
import com.ctsi.system.service.DictionaryTreeTypeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author: zhangjw
 * @Date: 2018/9/10 05:34
 * @Description:
 */
@RestController
public class DictionaryTreeController {

    private static final Logger logger = LoggerFactory.getLogger(DictionaryTreeController.class);

    @Autowired
    private DictionaryTreeDataService dictionaryTreeDataService;

    @Autowired
    private DictionaryTreeTypeService dictionaryTreeTypeService;

    @GetMapping(value = "/dicttree/types", produces = "application/json")
    @ResponseStatus(value = HttpStatus.OK)
    public UnifiedResponse<Page<DictionaryTreeType>> query(@RequestParam Map<String, Object> params, @RequestParam(defaultValue = Page.DEFAULT_PAGESIZE) Integer pageSize, @RequestParam Integer start) {
        Map<String, Object> param = UtilHttp.filterBlank(params);
        if (param.containsKey("nameLike")) {
            param.put("nameLike", "%".concat((String) param.get("nameLike")).concat("%"));
        }
        UserInfo user = SecurityUtil.getUser();
        param.put("tenementId", user.getTenementId());
        return UnifiedResponse.ok(this.dictionaryTreeTypeService.findByMulitCondition(param, start, pageSize));
    }

    @PostMapping(value = "/dicttree/typess", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public UnifiedResponse<Void> addType(@RequestBody AddTreeTypeRequest treeType) {
        DictionaryTreeType tt = treeType.toTreeType();
        UserInfo user = SecurityUtil.getUser();
        tt.setCreateAt(System.currentTimeMillis());
        tt.setCreateBy(user.getUserId());
        tt.setTenementId("common");
        tt.setDel(0);
        this.dictionaryTreeTypeService.insertDictionaryTreeType(tt);

        return UnifiedResponse.ok();
    }


    @GetMapping(value = "/dicttree/datas")
    @ResponseStatus(value = HttpStatus.OK)
    public UnifiedResponse<Page<Map<String, Object>>> queryData(@RequestParam Map<String, Object> params, @RequestParam(defaultValue = Page.DEFAULT_PAGESIZE) Integer pageSize, @RequestParam Integer start) {
        Map<String, Object> param = UtilHttp.filterBlank(params);
        UserInfo user = SecurityUtil.getUser();
        param.put("tenementId", user.getTenementId());
        return UnifiedResponse.ok(this.dictionaryTreeDataService.findByMulitCondition(param, start, pageSize));
    }

    @PostMapping(value = "/dicttree/datas", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseStatus(value = HttpStatus.OK)
    public UnifiedResponse<Void> addTreeData(@RequestBody AddTreeDataRequest addTreeDataRequest) {
        DictionaryTreeData data = addTreeDataRequest.toData();
        UserInfo user = SecurityUtil.getUser();
        data.setCreateBy(user.getUserId());
        data.setCreateAt(System.currentTimeMillis());
        data.setStatus("normal");
        // 处理level
        if (DictionaryTreeData.DEFAULT_ROOT.equals(data.getParentId())) {
            data.setLevel(1);
        } else {
            DictionaryTreeData parent = this.dictionaryTreeDataService.findDictionaryTreeDataById(data.getParentId());
            data.setLevel(parent.getLevel() + 1);
        }
        // TODO: 处理边界，level
        this.dictionaryTreeDataService.insertDictionaryTreeData(data);
        return UnifiedResponse.ok();
    }

    /**
     * 懒加载获取字典树 数据
     * @param typeId
     * @param parentId
     * @return
     */
    @GetMapping(value = "/dicttree/{typeId}/datas/{parentId}")
    @ResponseStatus(value = HttpStatus.OK)
    public UnifiedResponse<List<DictTreeDataResponse>> queryDataByParentId(@PathVariable("typeId") String typeId, @PathVariable("parentId") String parentId) {

        List<DictionaryTreeData> datas = this.dictionaryTreeDataService.findDataByTypeAndParentId(typeId,parentId);
        List<DictTreeDataResponse> responses =datas.stream().map(data -> {
            String id = data.getId();
            DictTreeDataResponse response = new DictTreeDataResponse();
            response.setCode(data.getCode());
            response.setId(data.getId());
            response.setName(data.getName());
            response.setParentId(data.getParentId());
            response.setLeaf(true);
            if (!this.dictionaryTreeDataService.isLeaf(id)) {
                // 为了说明还有子节点
                response.setChildren(Collections.emptyList());
                response.setLeaf(false);
            }
            return response;
        }).collect(Collectors.toList());

        return UnifiedResponse.ok(responses);
    }


    @PostMapping(value = "/dicttree/{typeId}/datas/{parentId}")
    @ResponseStatus(value = HttpStatus.OK)
    public UnifiedResponse<List<DictTreeDataResponse>> queryDataByParentIdAndriod(@PathVariable("typeId") String typeId, @PathVariable("parentId") String parentId) {
        List<DictionaryTreeData> datas = this.dictionaryTreeDataService.findDataByTypeAndParentId(typeId,parentId);
        List<DictTreeDataResponse> responses =datas.stream().map(data -> {
            String id = data.getId();
            DictTreeDataResponse response = new DictTreeDataResponse();
            response.setCode(data.getCode());
            response.setId(data.getId());
            response.setName(data.getName());
            response.setParentId(data.getParentId());
            response.setLeaf(true);
            if (!this.dictionaryTreeDataService.isLeaf(id)) {
                // 为了说明还有子节点
                response.setChildren(Collections.emptyList());
                response.setLeaf(false);
            }
            return response;
        }).collect(Collectors.toList());
        return UnifiedResponse.ok(responses);
    }


    @GetMapping(value = "/dicttree/{typeId}/datas")
    public UnifiedResponse<List<DictTreeDataDTO>> queryAllTreeData(@PathVariable("typeId") String typeId,
                                                                   @RequestParam(value = "level",required = false) Integer level){
        List<DictTreeDataDTO> datas = this.dictionaryTreeDataService.findTreeDataListByType(typeId,level == null? -1: level);
//        Map<String,List<DictionaryTreeData>> map = datas.stream().collect(Collectors.groupingBy(DictionaryTreeData::getParentId));
        return UnifiedResponse.ok(datas);
    }

    @PostMapping(value = "/dicttree/{typeId}/datas")
    public UnifiedResponse<List<DictTreeDataDTO>> queryAllTreeDataPost(@PathVariable("typeId") String typeId,@RequestParam(value = "level",required = false) Integer level){
        List<DictTreeDataDTO> datas = this.dictionaryTreeDataService.findTreeDataListByType(typeId,level == null? -1: level);
//        Map<String,List<DictionaryTreeData>> map = datas.stream().collect(Collectors.groupingBy(DictionaryTreeData::getParentId));
        return UnifiedResponse.ok(datas);
    }

    @PostMapping(value = "dicttree/selectDictTreeTypeById")
    @ResponseStatus(value = HttpStatus.OK)
    public UnifiedResponse<DictionaryTreeType> selectDictTreeTypeById(@RequestParam(value = "id")String id){
        DictionaryTreeType dictionaryTreeType = dictionaryTreeTypeService.selectDictTreeTypeById(id);
        return UnifiedResponse.ok(dictionaryTreeType);
    }
    @PostMapping(value = "dicttree/selectDictTreeDataById")
    @ResponseStatus(value = HttpStatus.OK)
    public UnifiedResponse<DictionaryTreeData> selectDictTreeDataById(@RequestParam(value = "id")String id){
        DictionaryTreeData dictionaryTreeData = dictionaryTreeDataService.selectDictTreeDataById(id);
        return UnifiedResponse.ok(dictionaryTreeData);
    }

    @PostMapping(value = "dicttree/updateDictTreeType",consumes = "application/json",produces = "application/json;charset=UTF-8")
    public UnifiedResponse<Integer> updateDictTreeType(@RequestBody DictionaryTreeType dictionaryTreeType){
        int i = dictionaryTreeTypeService.updateDictionaryTreeTypeByPKSelective(dictionaryTreeType);
        return UnifiedResponse.ok(i);
    }

    @PostMapping(value = "dicttree/updateDictTreeData",consumes = "application/json",produces = "application/json;charset=UTF-8")
    public UnifiedResponse<Integer> updateDictTreeData(@RequestBody DictionaryTreeData dictionaryTreeData ){
        int i = dictionaryTreeDataService.updateDictionaryTreeDataByPKSelective(dictionaryTreeData);
        return UnifiedResponse.ok(i);
    }
    @PostMapping(value = "dicttree/deleteDictTreeType")
    public UnifiedResponse<String> deleteDictTreeType(@RequestParam(value = "ids") String ids){
        if (UtilValidate.isNotEmpty(ids)) {
            String[] arr = ids.split(",");
            int result = Stream.of(arr).filter(id -> UtilValidate.isNotEmpty(id)).mapToInt(id -> {
                try {
                    DictionaryTreeType dict = new DictionaryTreeType();
                    dict.setId(id);
                    DictionaryTreeType dictionaryTreeType = dictionaryTreeTypeService.selectDictTreeTypeById(id);
                    if (UtilValidate.isNotEmpty(dictionaryTreeType.getTypeId())){
                        DictionaryTreeData dictionaryTreeData=new DictionaryTreeData();
                        dictionaryTreeData.setTypeId(dictionaryTreeType.getTypeId());
                        Long o = (Long) dictionaryTreeTypeService.selectDictTreeTypeIsLeaf(dictionaryTreeData);
                        if (o==0){
                            dict.setDel(1);
                            return this.dictionaryTreeTypeService.updateDictionaryTreeTypeByPKSelective(dict);
                        }else {
                            return 0;
                        }
                    }else {
                        return 0;
                    }
                }catch (Exception e){
                    logger.error("{}",e);
                    return 0;
                }
            }).sum();
            if(arr.length >1){
                return UnifiedResponse.ok("选中"+arr.length+"条数据，成功删除"+result+"条数据！");
            }else {
                return UnifiedResponse.ok("删除成功!");
            }
        }
        return UnifiedResponse.ok("删除成功!");
    }
    @PostMapping(value = "dicttree/deleteDictTreeData")
    public UnifiedResponse<String> deleteDictTreeData(@RequestParam(value = "ids") String ids){
        if (UtilValidate.isNotEmpty(ids)) {
            String[] arr = ids.split(",");
            int result = Stream.of(arr).filter(id -> UtilValidate.isNotEmpty(id)).mapToInt(id -> {
                try {
                    DictionaryTreeData dict = new DictionaryTreeData();
                    dict.setId(id);
                        boolean leaf = dictionaryTreeDataService.isLeaf(id);
                        if (leaf==true){
                            dict.setStatus("del");
                            return this.dictionaryTreeDataService.updateDictionaryTreeDataByPKSelective(dict);
                        }else {
                            return 0;
                        }
                }catch (Exception e){
                    logger.error("{}",e);
                    return 0;
                }
            }).sum();
            if(arr.length >1){
                return UnifiedResponse.ok("选中"+arr.length+"条数据，成功删除"+result+"条数据！");
            }else {
                return UnifiedResponse.ok("删除成功!");
            }
        }
        return UnifiedResponse.ok("删除成功!");
    }

    private List<DictTreeDataResponse> createTree(String parentId, Map<String,List<DictionaryTreeData>> map){
            if (map.get(parentId) == null) {
                return null;
            }else {
                return map.get(parentId)
                        .stream().filter(x->x.getParentId().equals(parentId)).sorted(Comparator.comparing(DictionaryTreeData::getOrder))
                        .map(x-> new DictTreeDataResponse(x.getId(),x.getParentId(),x.getName(),x.getCode(),createTree(x.getId(),map))
                        ).collect(Collectors.toList());
            }
    }


}
